package main

import (
	"net"
	"strings"
)

// User 用户类型
type User struct {
	// 用户名
	Name string
	// 用户地址
	Addr string
	// 用户绑定的channel
	C chan string
	// 用户绑定的Conn连接
	conn net.Conn
	// 用户所属的server
	server *Server
}

// NewUser 创建一个用户的接口
func NewUser(conn net.Conn, server *Server) *User {
	userAddr := conn.RemoteAddr().String()
	user := &User{
		Name:   userAddr,
		Addr:   userAddr,
		C:      make(chan string),
		conn:   conn,
		server: server,
	}

	// 启动监听当前user channel消息的goroutine
	go user.ListenMessage()
	return user
}

// ListenMessage 监听当前User channel的方法,一旦有消息,就发送给对应的客户端
func (u *User) ListenMessage() {
	for {
		msg := <-u.C

		u.conn.Write([]byte(msg + "\n"))
	}
}

// Online 用户上线业务
func (u *User) Online() {
	// 用户上线,将用户加入到onlineMap中
	u.server.mapLock.Lock()
	u.server.OnlineMap[u.Name] = u
	u.server.mapLock.Unlock()
	// 广播当前用户上线消息
	u.server.BroadCast(u, "已上线")
}

// Offline 用户下线业务
func (u *User) Offline() {
	// 用户下线,将用户从onlineMap中删除
	u.server.mapLock.Lock()
	delete(u.server.OnlineMap, u.Name)
	u.server.mapLock.Unlock()

	// 广播当前用户下线消息
	u.server.BroadCast(u, "已下线")
}

// DoMessage 用户处理消息业务
func (u *User) DoMessage(msg string) {
	if msg == "who" {
		// 查询当前在线用户有哪些
		u.server.mapLock.Lock()
		for _, user := range u.server.OnlineMap {
			onlineMsg := "[" + user.Addr + "]" + user.Name + ":在线..\n"
			u.SendMessage(onlineMsg)
		}
		u.server.mapLock.Unlock()
	} else if len(msg) > 7 && msg[:7] == "rename|" {
		// 消息格式:rename|zhang3
		//newName := strings.Split(msg, "|")[1]
		newName := msg[7:]
		// 判断name是否存在
		u.server.mapLock.Lock()
		_, ok := u.server.OnlineMap[newName]
		if ok {
			u.SendMessage("当前用户名已被使用!\n")
		} else {
			delete(u.server.OnlineMap, u.Name)
			u.server.OnlineMap[newName] = u
			u.Name = newName
			u.SendMessage("您已经更新用户名:" + u.Name + "\n")
		}
		u.server.mapLock.Unlock()
	} else if len(msg) > 4 && msg[:2] == "to" {
		// 消息格式:to|zhang3|text
		// 1.获取对方的用户名
		remoteName := strings.Split(msg, "|")[1]
		if remoteName == "" {
			u.SendMessage("消息格式不正确,请使用 \"to|zhagn3|text\"格式!\n")
			return
		}
		// 2.根据用户名得到对方user对象
		remoteUser, ok := u.server.OnlineMap[remoteName]
		if !ok {
			u.SendMessage("该用户不存在!\n")
			return
		}
		// 3.获取消息内容,通过对方的user对象将消息内容发送过去
		content := strings.Split(msg, "|")[2]
		if content == "" {
			u.SendMessage("无消息内容,请重发!\n")
			return
		}
		remoteUser.SendMessage(u.Name + "对您说:" + content + "\n")
	} else {
		u.server.BroadCast(u, msg)
	}
}

// SendMessage 给当前用户对应的客户端发送消息
func (u *User) SendMessage(msg string) {
	u.conn.Write([]byte(msg))
}
